package com.sbtr.util;

import org.junit.Test;

import java.util.Arrays;

/**
 *  @Author maojianping
 *  @Version 1.0
 *  矩阵计算常用工具类
 */
public class MatrixUtils {

      /**
   * 创建矩阵。
   *
   * @param rows 矩阵的行数。
   * @param cols 矩阵的列数。
   * @return 创建的矩阵。
   */
  public static double[][] createMatrix(int rows, int cols) {
    return new double[rows][cols];
  }

    /**
     * 矩阵转置
     * @param a 矩阵a
     * @return 返回a的转置矩阵
     */
    public static double[][] transpose(double[][] a) {
        int row = a.length;
        int col = a[0].length;
        double[][] c = new double[col][row];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                c[j][i] = a[i][j];
            }
        }
        return c;
    }

    /**
     * 矩阵转置
     * @param matrix 矩阵
     * @return 转置后的矩阵
     */
    public static int[][] transpose(int[][] matrix) {
        if (matrix == null) {
            return null;
        }
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] result = new int[n][m];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                result[j][i] = matrix[i][j];
            }
        }
        return result;
    }

      /**
   * 矩阵转置。
   *
   * @param matrix 要转置的矩阵。
   * @return 转置后的矩阵。
   */
  public static double[][] matrixTranspose(double[][] matrix) {
    int rows = matrix.length;
    int cols = matrix[0].length;

    double[][] result = new double[cols][rows];

    for (int i = 0; i < rows; i++) {
      for (int j = 0; j < cols; j++) {
        result[j][i] = matrix[i][j];
      }
    }

    return result;
  }

    /**
     * 矩阵加法
     * @param a 矩阵a
     * @param b 矩阵b
     * @return 返回a+b的矩阵
     */
    public static double[][] add(double[][] a, double[][] b) {
        int row = a.length;
        int col = a[0].length;
        double[][] c = new double[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                c[i][j] = a[i][j] + b[i][j];
            }
        }
        return c;
    }
    /**
     * 矩阵相加
     * @param A 矩阵A
     * @param B 矩阵B
     * @return A+B的结果矩阵
     */
    public static int[][] add(int[][] A, int[][] B) {
        if (A == null || B == null || A.length != B.length || A[0].length != B[0].length) {
            return null;
        }
        int m = A.length;
        int n = A[0].length;
        int[][] result = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                result[i][j] = A[i][j] + B[i][j];
            }
        }
        return result;
    }

  /**
   * 矩阵乘法。
   *
   * @param matrixA 矩阵 A。
   * @param matrixB 矩阵 B。
   * @return 矩阵乘积。
   */
  public static double[][] matrixMultiplication(double[][] matrixA, double[][] matrixB) {
    int aRows = matrixA.length;
    int aCols = matrixA[0].length;
    int bCols = matrixB[0].length;

    double[][] result = new double[aRows][bCols];

    for (int i = 0; i < aRows; i++) {
      for (int j = 0; j < bCols; j++) {
        for (int k = 0; k < aCols; k++) {
          result[i][j] += matrixA[i][k] * matrixB[k][j];
        }
      }
    }

    return result;
  }
    /**
     * 矩阵乘法
     * @param a 矩阵a
     * @param b 矩阵b
     * @return 返回a*b的矩阵
     */
    public static double[][] multiply(double[][] a, double[][] b) {
        int row1 = a.length;
        int col1 = a[0].length;
        int row2 = b.length;
        int col2 = b[0].length;
        if (col1 != row2) {
            throw new IllegalArgumentException("矩阵a的列数必须等于矩阵b的行数");
        }
        double[][] c = new double[row1][col2];
        for (int i = 0; i < row1; i++) {
            for (int j = 0; j < col2; j++) {
                for (int k = 0; k < col1; k++) {
                    c[i][j] += a[i][k] * b[k][j];
                }
            }
        }
        return c;
    }
    /**
     * 矩阵相乘
     * @param A 矩阵A
     * @param B 矩阵B
     * @return A*B的结果矩阵
     */
    public static int[][] multiply(int[][] A, int[][] B) {
        if (A == null || B == null || A[0].length != B.length) {
            return null;
        }
        int m = A.length;
        int n = B[0].length;
        int[][] result = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < A[0].length; k++) {
                    result[i][j] += A[i][k] * B[k][j];
                }
            }
        }
        return result;
    }

    /**
   * 矩阵求逆。
   *
   * @param matrix 要求逆的矩阵。
   * @return 求逆后的矩阵。
   */
  public static double[][] matrixInverse(double[][] matrix) {
    int n = matrix.length;

    // 创建一个新的矩阵，用于存储逆矩阵
    double[][] inverse = new double[n][n];

    // 将单位矩阵复制到逆矩阵中
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        inverse[i][j] = i == j ? 1 : 0;
      }
    }
    return  inverse;
  }

    /**
     * 创建字符串类型矩阵。
     *
     * @param rows 矩阵的行数。
     * @param cols 矩阵的列数。
     * @return 创建的矩阵。
     */
    public static String[][] createStrMatrix(int rows, int cols) {
        return new String[rows][cols];
    }

    /**
     * 字符串类型矩阵转置
     * @param a 矩阵a
     * @return 返回a的转置矩阵
     */
    public static String[][] transpose(String[][] a) {
        int row = a.length;
        int col = a[0].length;
        String[][] c = new String[col][row];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                c[j][i] = a[i][j];
            }
        }
        return c;
    }

    /**
     * 字符串类型矩阵相加
     * @param a 矩阵a
     * @param b 矩阵b
     * @return 返回a+b的矩阵
     */
    public static String[][] add(String[][] a, String[][] b) {
        int row = a.length;
        int col = a[0].length;
        String[][] c = new String[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                c[i][j] = a[i][j] + b[i][j];
            }
        }
        return c;
    }

    /**
     * 字符串类型矩阵相乘
     * @param a 矩阵a
     * @param b 矩阵b
     * @return 返回a*b的矩阵
     */
    public static String[][] multiply(String[][] a, String[][] b) {
        int row1 = a.length;
        int col1 = a[0].length;
        int row2 = b.length;
        int col2 = b[0].length;
        if (col1 != row2) {
            throw new IllegalArgumentException("字符串类型矩阵a的列数必须等于矩阵b的行数");
        }
        String[][] c = new String[row1][col2];
        for (int i = 0; i < row1; i++) {
            for (int j = 0; j < col2; j++) {
                for (int k = 0; k < col1; k++) {
                    c[i][j] += a[i][k] + b[k][j];
                }
            }
        }
        return c;
    }

    /**
     * Double类型测试矩阵各种计算
     */
    @Test
    public void testDoubleMatrix(){
      // 测试矩阵转置
      double[][] matrix = {{1, 2, 3}, {4, 5, 6}};
      double[][] transposedMatrix = MatrixUtils.matrixTranspose(matrix);
      System.out.println("转置后的矩阵：");
      for (double[] row : transposedMatrix) {
          System.out.println(Arrays.toString(row));
      }

     // 测试矩阵加法
      double[][] a = {{1, 2}, {3, 4}};
      double[][] b = {{5, 6}, {7, 8}};
      double[][] c = MatrixUtils.add(a, b);
      System.out.println("矩阵a+b：");
      for (double[] row : c) {
          System.out.println(Arrays.toString(row));
      }

      // 测试矩阵求逆
      double[][] matrix2 = {{1, 2}, {3, 4}};
      double[][] inverseMatrix = MatrixUtils.matrixInverse(matrix2);
      System.out.println("逆矩阵：");
      for (double[] row : inverseMatrix) {
          System.out.println(Arrays.toString(row));
      }
  }


    /**
     * 测试字符串类型矩阵
     */
    @Test
    public void testStrMatrixAll(){
      String[][] a = {{"1", "2", "3"}, {"4", "5", "6"}, {"1", "0", "1"}};
      String[][] b = {{"7", "8", "9"}, {"10", "11", "12"}, {"2", "2", "2"}};
      String[][] c = createStrMatrix(2, 3);
      System.out.println("a = " + Arrays.deepToString(a));
      System.out.println("b = " + Arrays.deepToString(b));
      System.out.println("c = " + Arrays.deepToString(c));
      System.out.println("a的转置矩阵 = " + Arrays.deepToString(transpose(a)));
      System.out.println("a+b的矩阵 = " + Arrays.deepToString(add(a, b)));
  }

}
